Skip to content

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) - #150

Merged
robercano-ghbot merged 2 commits into
mainfrom
feat/issue-124-rc-supervision
Jul 17, 2026
Merged

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124)#150
robercano-ghbot merged 2 commits into
mainfrom
feat/issue-124-rc-supervision

Conversation

@robercano-ghbot

Copy link
Copy Markdown
Collaborator

Closes #124.

Problem

claude-rc.service was Type=oneshot + RemainAfterExit=yes with ExecStart=tmux new -d .... tmux exits as soon as the detached session exists, so systemd reported the unit active forever even after the claude remote-control process inside the pane died. No Restart= could ever fire because systemd never saw a failure — the planner rotted silently (the exact reDeploy incident on template v4).

Fix — Option B (supervising wrapper, inline)

Chose Option B over the issue's stated Option A preference: claude remote-control renders a QR/status and currently runs in a tmux PTY, so it very likely needs a TTY, and this environment cannot run systemd/tmux/claude to prove TTY-independence. Option B preserves the proven tmux launch environment and the human tmux attach point, with no new template/MANIFEST/sync surface area.

  • Type=simple, Restart=on-failure, RestartSec=10s.
  • ExecStart is now a /bin/bash -c supervisor that launches the detached tmux session running the same inner exec claude remote-control ... (identical flags/PATH as before), then polls tmux has-session / tmux list-panes -F '#{pane_dead}' in a sleep 10 loop and exit 1 the instant the session/pane dies. systemd tracks that process as the main PID, so a dead planner transitions the unit to failed → restart within RestartSec with no operator action.
  • Detects both failure modes: session torn down (default remain-on-exit off) and lingering-but-dead pane (#{pane_dead}==1), belt-and-suspenders.
  • Version marker bumped v5 → v6 on both claude-rc.service copies (per the Release: bump plugin version (0.1.4 → 0.2.0) so the cron-less loop daemon reaches downstream installs #109/Release: bump plugin version 0.2.0 → 0.2.1 — ship the post-0.2.0 loop fixes to downstream installs #113 release pattern); the two copies remain byte-identical.
  • arm-loop.sh (installed + scaffold-template twin) comments/messaging updated to the accurate Type=simple + Restart=on-failure supervision story; journalctl inspect hint added; arm-loop marker bumped v5 → v6.

Acceptance

  • pkill -f remote-control → supervisor exits non-zero → Restart=on-failure relaunches the session within RestartSec (~10s detect + 10s RestartSec) with no operator action.
  • systemctl --user status claude-rc-<slug> now reflects real planner health (no permanent fake active).

Verification

Gates (self-adapter .claude/self/gates.json): build PASS · lint PASS · test PASS (incl. smoke-fanout.sh).
Reviewers (consensus=all): correctness (opus) APPROVE · tests (sonnet) APPROVE.
The inline supervisor control-flow was exercised via a stubbed tmux+claude harness (both death paths drive exit 1); the sed #-delimiter vs #{pane_dead} collision was checked and is a non-issue (the # delimits the sed expression, not the input).

Cannot be runtime-tested in CI

No systemd/tmux/claude available in-sandbox, so failed→restart rests on reasoned systemd semantics + verified shell control flow. Recommend a real-machine smoke (pkill -f remote-control after arming) before/soon after merge — the issue's acceptance itself acknowledges this.

Non-blocking follow-ups (out of scope for #124)

🤖 Generated with Claude Code

robercano and others added 2 commits July 16, 2026 22:23
…oneshot (issue #124)

Type=oneshot + RemainAfterExit=yes only tracked `tmux new -d`'s own exit, so
systemd reported "active" forever even after the `claude remote-control`
process inside the tmux pane crashed -- no Restart= could ever fire because
systemd never saw a failure.

Switch to Type=simple + Restart=on-failure + RestartSec=10s, with ExecStart
now an inline supervisor: it launches the same detached tmux session as
before (preserving the proven TTY environment `claude remote-control` needs
for its QR/status rendering, and the human tmux-attach point), then blocks,
polling every 10s whether the session/pane is still alive, and exits
non-zero the instant it is not. That makes ExecStart itself the long-lived
process systemd tracks, so a dead planner now transitions the unit to
failed -> restarting within RestartSec, self-healing with no operator
action. Verified the inline supervisor's quoting/control-flow end-to-end
against a stubbed tmux+claude harness (pane-death and session-kill paths
both correctly exit 1 within one poll cycle).

Bump the claude-rc-service marker v5 -> v6 in both the template and this
repo's installed copy (kept byte-identical). Update arm-loop.sh's stale
oneshot-era comments/hints to match the new supervision story.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rc wording (issue #124)

The setup-skill template still described the old Type=oneshot +
RemainAfterExit rationale for the claude-rc restart step and closing
status/inspect block, while the installed script and both .service
units had already moved to Type=simple + Restart=on-failure (issue
#124). Mirror the same wording in the template and bump both files'
@orchestrator-managed marker to v6 so a fresh scaffold no longer ships
a v6 unit next to a stale v5 banner describing broken oneshot behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

25 similar comments
@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

26 similar comments
@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

fix(loop): systemd actually supervises claude-rc (no more fake-forever oneshot) (#124) (not yet reviewed)

@robercano-ghbot
robercano-ghbot merged commit 6ba9385 into main Jul 17, 2026
9 checks passed
@robercano-ghbot
robercano-ghbot deleted the feat/issue-124-rc-supervision branch July 17, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

claude-rc.service: systemd cannot see claude remote-control dying inside tmux — planner session goes silently unresponsive

2 participants